﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Xml.XPath;
using System.IO;
using System.Xml;
using HtmlAgilityPack;
using System.Data;

namespace AirChina
{
    /// <summary>
    /// 中国国际航空数据爬取服务
    /// </summary>
    public class AirChinaService
    {
        /// <summary>
        /// 构造方法
        /// </summary>
        public AirChinaService()
        {
        }

        /// <summary>
        /// 获取出境游页面
        /// </summary>
        /// <returns>出境游页面所有字符</returns>
        public string GetProductsPage(string currentPage)
        {
            WebClient client = new WebClient();
            string postString = "sort=&keyWord=&sortType=&maxPrice=&minPrice=&changeCity=&departCity=&arriveCity=&productType=2&flightType=&trvalGroupOnly=&currentpage=" + currentPage;
            byte[] postData = Encoding.UTF8.GetBytes(postString);
            client.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36");
            client.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded");
            var data = client.UploadData("http://tuan.airchina.com/index.htm", "POST", postData);
            string returnStr = Encoding.UTF8.GetString(data);
            return returnStr;
        }

        /// <summary>
        /// 获取产品列表
        /// </summary>
        /// <param name="text">html页面代码</param>
        /// <returns>产品列表</returns>
        public List<string> GetProduct(string text)
        {
            List<string> list = new List<string>();
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(text);
            HtmlNode node = doc.DocumentNode.SelectSingleNode("//ul[@id='products']");


            HtmlNodeCollection CNodes = node.ChildNodes;

            //清除文本节点#text
            for (int i = 0; i < CNodes.Count; )
            {
                if (CNodes[i].InnerHtml.Trim() == "")
                {
                    CNodes.Remove(CNodes[i]);
                }
                else
                {
                    i++;
                }
            }
            //遍历节点，抓取产品名称
            foreach (HtmlNode n in CNodes)
            {
                if (doc.DocumentNode.SelectSingleNode(n.XPath + "/div[2]/div[1]/h1") == null)
                {
                    string tempStr =
                        doc.DocumentNode.SelectSingleNode(n.XPath + "/div[2]/div[1]/em[1]").InnerText + "到" +
                        doc.DocumentNode.SelectSingleNode(n.XPath + "/div[2]/div[1]/em[2]").InnerText.Trim() + " " +
                        doc.DocumentNode.SelectSingleNode(n.XPath + "/div[2]/div[1]/br[1]/em[1]").InnerText.Trim() + "到" +
                        doc.DocumentNode.SelectSingleNode(n.XPath + "/div[2]/div[1]/br[1]/em[2]").InnerText.Trim();
                    //解析js字符串：showDetail('7125','tianjin')
                    string jsStr = doc.DocumentNode.SelectSingleNode(n.XPath).Attributes[1].Value;

                    list.Add(tempStr + Js2Str(jsStr));

                }
                else
                {
                    list.Add(doc.DocumentNode.SelectSingleNode(n.XPath + "/div[2]/div[1]/h1").InnerText +
                        Js2Str(doc.DocumentNode.SelectSingleNode(n.XPath).Attributes[1].Value));
                }
            }
            return list;
        }

        /// <summary>
        /// 获取出境游页面总数
        /// </summary>
        /// <param name="text">页面的html代码</param>
        /// <returns>出境游页面总数</returns>
        public int GetPageNumbers(string text)
        {
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(text);
            HtmlNode node = doc.DocumentNode.SelectSingleNode("/html/body/div[5]/div[4]");
            HtmlNodeCollection CNodes = node.ChildNodes;
            int page = CNodes.Count / 2 - 2;//包含文本节点#text,所以除以2
            return page;
        }

        /// <summary>
        /// js字符串转换为id和city
        /// </summary>
        /// <param name="jsStr">js字符串</param>
        /// <returns></returns>
        private string Js2Str(string jsStr)
        {
            //showDetail('7125','tianjin')
            string[] s = jsStr.Split('\'');
            return "-" + s[1] + "-" + s[3];
        }

        /// <summary>
        /// 获取详细信息页面
        /// </summary>
        /// <param name="id">城市编号</param>
        /// <param name="city">城市拼音</param>
        /// <returns></returns>
        public string GetDetailPage(string id, string city)
        {
            WebClient client = new WebClient();
            client.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            client.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36");
            client.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded");
            #region 计算加0个数

            string idStr = "";
            int num = 7 - id.Length;
            for (int i = 0; i < num; i++)
            {
                idStr += "0";
            }
            idStr += id;

            #endregion
            var data = client.DownloadData("http://tuan.airchina.com/team-1" + idStr + "-" + city + ".html");
            string returnStr = Encoding.UTF8.GetString(data);
            return returnStr;
        }

        /// <summary>
        /// 详细信息页面数据解析
        /// </summary>
        /// <param name="text">详细信息页面html代码</param>
        /// <returns></returns>
        public List<DetailModel> DataAnalysis(string text)
        {

            List<DetailModel> list = new List<DetailModel>();
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(text);
            HtmlNode node = doc.DocumentNode.SelectSingleNode("//*[@id=\"left\"]/div[1]/table");
            HtmlNodeCollection CNodes = node.ChildNodes;

            //清除文本节点#text
            for (int i = 0; i < CNodes.Count; )
            {
                if (CNodes[i].InnerHtml.Trim() == "")
                {
                    CNodes.Remove(CNodes[i]);
                }
                else
                {
                    i++;
                }
            }

            for (int i = 0; i < CNodes.Count; i++)
            {
                var dom = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[2]");
                if (dom == null)
                {
                    continue;
                }
                DetailModel dm = new DetailModel();

                //页面中第一行数据
                dm.goAirport = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[4]").InnerText.Trim();
                dm.endDateTime = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[5]/text()").InnerText.Trim();
                dm.groupPurchase = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[6]/strong/text()[2]").InnerText.Trim();
                dm.remainSeat = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[6]/text()[3]").InnerText.Trim().Replace("剩余座位：", "");
                if (doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[2]/text()[3]") == null)
                {
                    dm.goNo = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[2]/text()[2]").InnerText;
                    dm.goDateTime = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[2]/text()[1]").InnerText;
                }
                else
                {
                    dm.goDateTime = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[2]/text()[2]").InnerText.Trim();
                    dm.goNo = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[2]/text()[3]").InnerText;
                    i++;
                    //页面中第二行数据
                    dm.returnDateTime = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[1]/text()[2]").InnerText.Trim();
                    dm.returnNo = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[1]/text()[3]") == null ? "" : doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[1]/text()[3]").InnerText;

                    dm.returnAirport = doc.DocumentNode.SelectSingleNode(CNodes[i].XPath + "/td[3]").InnerText.Trim();
                }

                list.Add(dm);
            }
            return list;
        }
    }

    /// <summary>
    /// 返回数据模型
    /// </summary>
    public class DetailModel
    {
        public string goDateTime { get; set; } //起飞日期

        public string returnDateTime { get; set; } //回程日期

        public string goNo { get; set; } //去程航班号

        public string returnNo { get; set; } //回程航班号

        public string goAirport { get; set; } //去程机场

        public string returnAirport { get; set; } //回程机场

        public string endDateTime { get; set; } //结束日期

        public string groupPurchase { get; set; } //团购价

        public string remainSeat { get; set; } //剩余座位数
    }
}
